home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / FREENET / MELL / NETLIB00 / NetLib / c / serv < prev   
Text File  |  1995-01-30  |  4KB  |  223 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "netdb.h"
  6. #include "netinet/in.h"
  7. #include "sys/byteorder.h"
  8. #include "sys/socket.h"
  9.  
  10. #include "socketlib.h"
  11.  
  12. /*
  13.  * File handle for the services file
  14.  */
  15. static FILE *servfile = NULL;
  16.  
  17. /*
  18.  * Keep the file open between calls to these routines?
  19.  */
  20. static int keepopen = 0;
  21.  
  22. /*
  23.  * Local routines
  24.  */
  25. static int __setservent(int allowrewind);
  26. static struct servent *__getservent(void);
  27.  
  28. /*
  29.  * Open and rewind the services file
  30.  */
  31. int setservent(int stayopen)
  32. {
  33.   /* Record whether the file should be kept open */
  34.   keepopen = stayopen;
  35.  
  36.   return __setservent(1);
  37. }
  38.  
  39. /*
  40.  * Do the real work of opening/rewinding the services file
  41.  */
  42. static int __setservent(int allowrewind)
  43. {
  44.   /* Open or rewind the file as necessary */
  45.   if (servfile) {
  46.     if (allowrewind)
  47.       rewind(servfile);
  48.   } else {
  49.     servfile = fopen("InetDBase:Services", "r");
  50.   }
  51.  
  52.   return (servfile == NULL) ? -1 : 0;
  53. }
  54.  
  55. /*
  56.  * Fetch the next entry from the services file
  57.  */
  58. struct servent *getservent()
  59. {
  60.   struct servent *serv;
  61.  
  62.   /* Open the file if necessary */
  63.   if (servfile == NULL)
  64.     if (__setservent(0) == -1)
  65.       return NULL;
  66.  
  67.   /* Do the actual read */
  68.   serv = __getservent();
  69.  
  70.   /* Close the file unless the user has prohibited it */
  71.   if (!keepopen)
  72.     endservent();
  73.  
  74.   return serv;
  75. }
  76.  
  77. /*
  78.  * Do the real work of getting an entry from the file
  79.  */
  80. struct servent *__getservent()
  81. {
  82.   static struct servent serv = {
  83.     NULL, NULL, 0, NULL
  84.   };
  85.  
  86.   char **item;
  87.   char *line;
  88.   char *element;
  89.   int  aliases;
  90.  
  91.   /* Free up any memory in use */
  92.   if (serv.s_name) {
  93.     for (item = serv.s_aliases; *item; item++)
  94.       free(*item);
  95.     free(serv.s_name);
  96.     free(serv.s_aliases);
  97.     free(serv.s_proto);
  98.  
  99.     serv.s_name = NULL;
  100.   }
  101.  
  102.   /* Read a line from the file */
  103.   if ((line = __socketlib_readline(servfile)) == NULL)
  104.     return NULL;
  105.  
  106.   /* Extract the offical service name from the line */
  107.   element = strtok(line, " \t");
  108.   serv.s_name = strdup(element);
  109.  
  110.   /* Extract the port number from the line */
  111.   element = strtok(NULL, "/");
  112.   serv.s_port = htons(atoi(element));
  113.  
  114.   /* Extract the protocol name from the line */
  115.   element = strtok(NULL, " \t");
  116.   serv.s_proto = strdup(element);
  117.  
  118.   /* Initialise the alias list */
  119.   serv.s_aliases = malloc(sizeof(char *));
  120.   serv.s_aliases[0] = NULL;
  121.   aliases = 1;
  122.  
  123.   /* Extract the aliases */
  124.   while ((element = strtok(NULL, " \t")) != NULL)
  125.   {
  126.      aliases += 1;
  127.      serv.s_aliases = realloc(serv.s_aliases, aliases * sizeof(char *));
  128.      serv.s_aliases[aliases-2] = strdup(element);
  129.      serv.s_aliases[aliases-1] = NULL;
  130.   }
  131.  
  132.   return &serv;
  133. }
  134.  
  135. /*
  136.  * Close the services file
  137.  */
  138. int endservent()
  139. {
  140.   int status = 0;
  141.  
  142.   /* If its open, close it */
  143.   if (servfile) {
  144.     status = fclose(servfile);
  145.     servfile = 0;
  146.   }
  147.  
  148.   return status;
  149. }
  150.  
  151. /*
  152.  * Search the services file for a given service name
  153.  */
  154. struct servent *getservbyname(const char *name, const char *proto)
  155. {
  156.   struct servent *serv;
  157.   char          **alias;
  158.  
  159.   /* Open/rewind the file */
  160.   if (__setservent(1) == -1)
  161.     return NULL;
  162.  
  163.   /* Look through the file for a match */
  164.   while ((serv = __getservent()) != NULL) {
  165.  
  166.     /* Give up now if the protocol doesn't match */
  167.     if (proto && (strcmp(serv->s_proto, proto) != 0))
  168.       continue;
  169.  
  170.     /* Does the offical name match? */
  171.     if (strcmp(serv->s_name, name) == 0)
  172.       break;
  173.  
  174.     /* Do any of the aliases match? */
  175.     for (alias = serv->s_aliases; *alias; alias++)
  176.     {
  177.       if (strcmp(*alias, name) == 0)
  178.         break;
  179.     }
  180.  
  181.     /* Did any of the aliases match? */
  182.     if (*alias)
  183.       break;
  184.   }
  185.  
  186.   /* Close the file unless the user has prohibited it */
  187.   if (!keepopen)
  188.     endservent();
  189.  
  190.   return serv;
  191. }
  192.  
  193. /*
  194.  * Search the services file for a given port
  195.  */
  196. struct servent *getservbyport(int port, const char *proto)
  197. {
  198.   struct servent *serv;
  199.  
  200.   /* Open/rewind the file */
  201.   if (__setservent(1) == -1)
  202.     return NULL;
  203.  
  204.   /* Look through the file for a match */
  205.   while ((serv = __getservent()) != NULL) {
  206.  
  207.     /* Give up now if the protocol doesn't match */
  208.     if (proto && (strcmp(serv->s_proto, proto) != 0))
  209.       continue;
  210.  
  211.     /* If the port matches, we've found it */
  212.     if (serv->s_port == port)
  213.       break;
  214.  
  215.   }
  216.  
  217.   /* Close the file unless the user has prohibited it */
  218.   if (!keepopen)
  219.     endservent();
  220.  
  221.   return serv;
  222. }
  223.